package pacs_server

import (
	"encoding/json"
	"errors"
	"gitee.com/uni-minds/bridge-pacs/global"
	"gitee.com/uni-minds/bridge-pacs/tools"
)

// region Func Series

func (pi *PacsServer) FindSeriesByIdLocal(seriesId string) (info global.SeriesInfo, err error) {
	data, err := pi.DbSeriesHandler().Where("series_id", seriesId).First()
	if err != nil {
		return info, err
	}

	info, err = pi.decodeSeriesInfo(data)
	if err != nil {
		return info, err
	} else if info.SeriesId != seriesId {
		return info, errors.New("no series")
	} else {
		return info, nil
	}
}

func (pi *PacsServer) FindSeriesByIdsLocal(seriesIds []string) (infos []global.SeriesInfo, err error) {
	var data []interface{}

	for _, seriesId := range seriesIds {
		data = append(data, seriesId)
	}

	ret, err := pi.DbSeriesHandler().WhereIn("series_id", data).Get()
	if err != nil {
		return nil, err
	}

	infos, err = pi.decodeSeriesInfos(ret)
	if err != nil {
		return nil, err
	}

	return infos, nil
}

func (pi *PacsServer) SeriesUpdateLabelCore(seriesId string, data map[string]interface{}) (err error) {
	data["label_update_datetime"] = tools.TimeEncodeNow()
	_, err = pi.DbSeriesHandler().Data(data).Where("series_id", seriesId).Update()
	//pi.Logf("Series label update %d records.\n", i)
	return err
}
func (pi *PacsServer) SeriesUpdateTag(seriesId string, key, value string) (err error) {
	m := map[string]interface{}{key: value}
	return pi.dbUpdateSeries(seriesId, m)
}
func (pi *PacsServer) SeriesUpdateLabelTag(seriesId string, key, value string) (err error) {
	m := map[string]interface{}{key: value}
	return pi.SeriesUpdateLabelCore(seriesId, m)
}
func (pi *PacsServer) SeriesUpdateAll(seriesId string, info global.SeriesInfo) (err error) {
	var data map[string]interface{}
	bs, _ := json.Marshal(info)
	if err = json.Unmarshal(bs, &data); err != nil {
		return err
	}
	return pi.dbUpdateSeries(seriesId, data)
}

func (pi *PacsServer) SeriesUpdateInsertInstanceId(seriesId, instanceId string) (err error) {
	info, err := pi.FindSeriesByIdLocal(seriesId)
	if err != nil {
		return err
	}

	result, _, err := tools.IdStrInsertIdStr(info.IncludeInstances, instanceId)
	if err != nil {
		return err
	} else {
		return pi.SeriesUpdateTag(seriesId, "include_instances", result)
	}
}

func (pi *PacsServer) RemoveSeries(studiesId string, seriesId string, isRemoveInstances bool) (err error) {
	var info global.SeriesInfo

	if seriesId == "undefined" {
		seriesId = ""

	} else {
		if info, err = pi.FindSeriesByIdLocal(seriesId); err != nil {
			return err
		}

		if isRemoveInstances {
			pi.Logf("start removing instances: %s\n", info.IncludeInstances)
			for _, instanceId := range tools.IdStrDecodeString(info.IncludeInstances) {
				if err = pi.RemoveInstance(instanceId); err != nil {
					pi.Logf("E remove instance %s: %s\n", instanceId, err.Error())
				}
			}
		}

		info, err = pi.FindSeriesByIdLocal(seriesId)
		if err == nil {
			pi.Log("Warning force remove series")
			if err = pi.dbRemoveSeries(seriesId); err != nil {
				pi.Logf("E remove series %s: %s\n", seriesId, err.Error())
			}
		}
	}

	err = pi.StudiesRemoveSeriesId(studiesId, seriesId)

	return err
}

func (pi *PacsServer) SeriesRemoveInstanceId(seriesId, instanceId string) (err error) {
	info, err := pi.FindSeriesByIdLocal(seriesId)
	if err != nil {
		pi.Logf("E series remove instance: %s/%s\n", seriesId, instanceId)
		return nil
	}

	result, cnt, err := tools.IdStrRemoveIdStr(info.IncludeInstances, instanceId)

	if err != nil {
		return err

	} else if cnt < 1 {
		if err = pi.dbRemoveSeries(seriesId); err != nil {
			pi.Logf("E removing series: %s\n", err.Error())
		}
		return pi.StudiesRemoveSeriesId(info.StudiesId, seriesId)

	} else {
		return pi.SeriesUpdateTag(seriesId, "include_instances", result)
	}
}

func (pi *PacsServer) SeriesUpdateLabel(seriesId string, label global.LabelSeries) (err error) {
	seriesInfo, err := pi.FindSeriesByIdLocal(seriesId)
	if err != nil {
		return err
	}

	if !label.OpOverride {
		if ok, err := pi.StudiesCheckPermissionAuthor(seriesInfo.StudiesId, label.Uid); err != nil {
			return err
		} else if !ok {
			return errors.New("user has no permission")
		}
	}

	if label.OpRemove {
		seriesInfo.LabelInfoAttend = ""
		seriesInfo.LabelMemo = ""
	} else {
		seriesInfo.LabelInfoAttend = label.InfoAttend
		seriesInfo.LabelMemo = label.Memo
	}
	return pi.SeriesUpdateAll(seriesId, seriesInfo)
}
func (pi *PacsServer) SeriesUpdateLabelMemo(seriesId string, memo string) (err error) {
	return pi.SeriesUpdateLabelTag(seriesId, "label_memo", memo)
}

func (pi *PacsServer) CheckSeriesPermissionAuthor(id string, uid int) (ok bool, err error) {
	seriesInfo, err := pi.FindSeriesByIdLocal(id)
	if err != nil {
		return false, err
	}

	return pi.StudiesCheckPermissionAuthor(seriesInfo.StudiesId, uid)
}
func (pi *PacsServer) CheckSeriesPermissionReview(id string, uid int) (ok bool, err error) {
	seriesInfo, err := pi.FindSeriesByIdLocal(id)
	if err != nil {
		return false, err
	}

	return pi.StudiesCheckPermissionReview(seriesInfo.StudiesId, uid)
}

// endregion
